class ThhuKms {
    static kmsPeerOptions= {
        configuration: {
            "iceServers": [
                {
                    urls: "stun:223.68.161.139:3478"
                },
                {
                    urls: ["turn:223.68.161.139:3478"],
                    username: "kurento",
                    credential: "kurento"
                }
            ]
        },
        mediaConstraints: {
            audio: true,
            video: {width: {exact: 1280}, height: {exact: 720}}
        }
    };
    static kmsPeerTypes = {
        send: kurentoUtils.WebRtcPeer.WebRtcPeerSendonly,
        rec: kurentoUtils.WebRtcPeer.WebRtcPeerRecvonly,
        sendRec: kurentoUtils.WebRtcPeer.WebRtcPeerSendrecv
    };
    static kmsPeerTypeList = [
        kurentoUtils.WebRtcPeer.WebRtcPeerSendonly,
        kurentoUtils.WebRtcPeer.WebRtcPeerRecvonly,
        kurentoUtils.WebRtcPeer.WebRtcPeerSendrecv
    ];
    static isNull = function (data) {
        var res = (!data) || (data==null) || (data=="");
        return res;
    };
    static cb = function (callback,p0,p1,p2) {
        if( callback){
            try{
                callback(p0,p1,p2);
            }
            catch (e) {
                console.log(e)
            }
        }
    };
    static newId = function (header , split) {
        var res = [header , ( new Date()).getTime() , parseInt(1000*Math.random())].join(split);
        return res;
    };
    static createNewPushRecPeer = function (pipe , pId , localVideo , remoteVideo , tag , onCreate ) {
        try{
            if ( !pId || pId==null || pId=="" ){
                pId = THhRoom.newId("pId","");
            }
            if( THhRoom.isNull(localVideo)){
                localVideo = document.createElement('video');
                localVideo.setAttribute('id', ['localVideo',pId].join('_'));
                localVideo.setAttribute('autoplay','true');
            }
            if( THhRoom.isNull(remoteVideo)){
                remoteVideo = document.createElement('video');
                remoteVideo.setAttribute('id', ['remoteVideo',pId].join('_'));
                remoteVideo.setAttribute('autoplay','true');
            }
            var opts = JSON.parse(JSON.stringify(kmsPeerOptions));
            opts.localVideo = localVideo;
            opts.remoteVideo = remoteVideo;
            var pusherMsgBody = {
                pId: pId ,
                tag: tag ,
                endKmsId:""
            }
            var peer = kmsPeerTypes.sendRec(opts,function () {
                peer.pId = pId;
                peer.tag = tag;
                pipe.create("WebRtcEndpoint", function (erEnd , end) {
                    ThhuKms.kmsBindPeerEnd(peer , end , function () {
                        peer.free = function(onFree){
                            try{
                                peer.peerconnection.close();
                                peer.end.release(function () {
                                    peer.end = null;
                                    peer.destroy();
                                    peer = null;
                                    onFree();
                                })
                            }
                            catch (erPeer) {
                                console.log(erPeer);
                            }
                        };
                        end.setName("pId_PushRecPeer_"+pId, function (erName, name) {
                            pusherMsgBody.endKmsId = end.id;
                            peer.pusherMsgBody = pusherMsgBody;
                            ThhuKms.kmsSetHDWebRtcEndpoint(end , function () {
                                THhRoom.cb(onCreate, peer, end);
                            })
                        })
                    });
                })
            })
        }
        catch (e) {
            console.log(e)
        }
    };
    static createNewRecPeer = function (pipe ,pId ,remoteVideo , tag , onCreate ) {
        try{
            if ( !pId || pId==null || pId=="" ){
                pId = ThhuKms.newId("pId","");
            }
            if( ThhuKms.isNull(remoteVideo)){
                remoteVideo = document.createElement('video');
                remoteVideo.setAttribute('id', ['remoteVideo',pId].join('_'));
                remoteVideo.setAttribute('autoplay','true');
            }
            var opts = JSON.parse(JSON.stringify(kmsPeerOptions));
            opts.remoteVideo = remoteVideo;
            var peer = kmsPeerTypes.rec(opts,function () {
                peer.pId = pId;
                peer.tag = tag;
                pipe.create("WebRtcEndpoint", function (erEnd , end) {
                    ThhuKms.kmsBindPeerEnd(peer , end , function () {
                        peer.free = function(onFree){
                            try{
                                peer.peerConnection.close();
                                peer.endpoint.release(function () {
                                    peer.endpoint = null;
                                    peer = null;
                                    onFree();
                                })
                            }
                            catch (erPeer) {
                                console.log(erPeer);
                            }
                        };
                        end.setName("pId_RecPeer_"+pId, function (erName, name) {
                            ThhuKms.cb(onCreate, peer, end);
                        })
                    });
                })
            })
        }
        catch (e) {
            console.log(e)
        }
    };
    static kmsBindPeerEnd = function (peer , endpoint , callback) {
        try{
            var setCandidateEvent = function (peer, endpoint) {
                try {
                    if (peer && endpoint) {
                        endpoint.on('OnIceCandidate', function (event) {
                            var candidate = event.candidate;
                            peer.addIceCandidate(candidate);
                            console.log(candidate);
                            console.log('candidate w->p')
                        });
                        peer.on('icecandidate', function (candidate) {
                            var iceCandidate = kurentoClient.register.complexTypes.IceCandidate(candidate);
                            endpoint.addIceCandidate(iceCandidate);
                            console.log(iceCandidate,candidate);
                            console.log('candidate p->w')

                        });
                    }
                } catch (e) {
                    ;
                }
            }
            if (endpoint && peer) {
                peer.generateOffer(function (errorPeerGenerateOffer, sdpOffer) {
                    if (errorPeerGenerateOffer && callback) {
                        callback(errorPeerGenerateOffer, null);
                    } else {
                        endpoint.processOffer(sdpOffer, function (errorSdpOffer, sdpAnswer) {
                            if (errorSdpOffer && callback) {
                                console.log("process sdpOffer error.", errorSdpOffer)
                                callback(errorSdpOffer, null);
                            } else {
                                setCandidateEvent(peer, endpoint);
                                peer.processAnswer(sdpAnswer);
                                endpoint.gatherCandidates(function (errorGatherCandidates) {
                                    if (errorGatherCandidates && callback) {
                                        console.log('webRtcPoint gatherCandidates error.', errorGatherCandidates)
                                        callback(errorGatherCandidates, null);
                                    } else {
                                        peer.endpoint = endpoint;
                                        endpoint.peer = peer;
                                        setCandidateEvent(peer, endpoint);
                                        if (callback) {
                                            callback(null, {endpoint: endpoint, peer: peer});
                                        }
                                    }
                                });
                            }
                        });
                    }
                });
            } else {
                if (callback) {
                    callback({error: "endPoint or peer is null."}, null);
                }
            }

        }
        catch (e) {
            console.log(e);
        }
    };
    static kmsSetHDWebRtcEndpoint = function ( end, onSet ) {
        try{
            ThhuKms.kmsSetWebRtcEndpointQuailty(end , 3000 , 1500, onSet);
        }
        catch (e) {
            console.log(e);
        }
    };
    static kmsSetSDWebRtcEndpoint = function ( end, onSet ) {
        try{
            ThhuKms.kmsSetWebRtcEndpointQuailty(end , 1000 , 500, onSet);
        }
        catch (e) {
            console.log(e);
        }
    };
    static kmsSetWebRtcEndpointQuailty = function ( end, maxBandWidth, minBndWidth , onSet ) {
        try{
            end.setMaxVideoRecvBandwidth(maxBandWidth).then(()=>{
                return end.setMaxVideoRecvBandwidth(maxBandWidth);
            }).then(()=>{
                return end.setMaxVideoSendBandwidth(maxBandWidth);
            }).then(()=>{
                return end.setMinVideoRecvBandwidth(minBndWidth);
            }).then(()=>{
                return end.setMinVideoSendBandwidth(minBndWidth);
            }).then(()=>{
                onSet();
            });
        }
        catch (e) {
            console.log(e);
        }
    };
    static getDevices = function (onGet) {
        try{
            var res ={};
            navigator.mediaDevices.enumerateDevices().then(function (devs) {
                try {
                    for (var i = 0; i < devs.length; i++) {
                        var item = devs[i];
                        if (!res[item.kind]) {
                            res[item.kind] = []
                        }
                        res[item.kind].push(item);
                    }
                }
                catch (er) {
                    console.log(er)
                }
                ThhuKms.cb( onGet , res);
            }).catch(function () {
                ThhuKms.cb( onGet , res);
            });
        }
        catch (e) {
            console.log(e);
        }
    };
    static acSetCamera = function ( peer ,  cameraDeviceId ,onSetCamera) {
        var me = this;
        try{
            if (window.rtcVideoStream) {
                window.rtcVideoStream.getTracks().forEach(track => {
                    if( track.kind=="video") {
                        track.stop();
                    }
                });
            }
            var constraints = {video: {deviceId: cameraDeviceId , height:{exact:720} , width:{exact:1280}}};
            var sender= null;
            navigator.mediaDevices.getUserMedia(constraints).then(function (stream) {
                try {
                    window.rtcVideoStream = stream;
                    peer.localVideo.srcObject = stream;
                    let videoTrack = stream.getVideoTracks()[0];
                    sender = peer.peerConnection.getSenders().find(function (s) {
                        return s.track.kind == videoTrack.kind;
                    });
                    sender.replaceTrack(videoTrack);
                    ThhuKms.cb(onSetCamera);
                }
                catch (eSet) {
                    ThhuKms.cb( onSetCamera);
                }
            }).catch(function () {
                ThhuKms.cb(onSetCamera);
            });
        }
        catch (e) {
            console.log(e);
        }
    };
    static acSwitchCamera = function (peer) {
        var me = this;
        try{
            var ids =[
                peer.devices.videoinput[0].deviceId ,
                peer.devices.videoinput[peer.devices.videoinput.length-1].deviceId
            ];
            var cameraId = (
                peer.cameraId  &&
                peer.cameraId !=null &&
                peer.cameraId.length>0 )?peer.cameraId : "";
            cameraId = cameraId == ids[1]?ids[0]:ids[1];
            ThhuKms.acSetCamera(peer , cameraId , function () {
                peer.cameraId = cameraId;
            })
        }
        catch (e) {
            console.log(e);
        }
    };
    static acToggleAudioMute = function (peer) {
        var res = false;
        try{
            var tracks = $.grep(peer.localVideo.srcObject.getTracks(), function (track) {
                return track.kind === 'audio';
            });
            if(tracks.length>0){
                var track = tracks[0];
                track.enabled = !track.enabled;
                res = track;
            }
        }
        catch (e) {
            console.log(e);
        }
        return res;
    };
    static acToggleVideoMute = function (peer) {
        try{
            peer.peerConnection.videoEnabled = !peer.peerConnection.videoEnabled;
        }
        catch (e) {
            console.log(e);
        }
    };
    static acTogglePlayVolume = function (peer) {
        try{
            peer.remoteVideo.volume = peer.remoteVideo.volume==0?1:0;
        }
        catch (e) {
            console.log(e);
        }
    };
    static acShareScreen = function (peer ,width , height) {
        try{
            var wWidth = width?width : $(window).width();
            var wHeight = height?height: $(window).height();
            var screenConstraints = {video: {width: {max:wWidth}, height: {max: wHeight}}, audio: true};
            var sender= null;
            if (navigator.mediaDevices.getDisplayMedia) {
                navigator.mediaDevices.getDisplayMedia(screenConstraints).then(
                    function (stream) {
                        let videoTrack = stream.getVideoTracks()[0];
                        peer.localVideo.srcObject = stream;
                        sender = peer.peerConnection.getSenders().find(function (s) {
                            return s.track.kind == videoTrack.kind;
                        });
                        sender.track.stop();
                        sender.replaceTrack(videoTrack);
                    }
                )
            }
        }
        catch (e) {
            console.log(e);
        }
    };
    static acFullScreen = function (peer) {
        var element = peer.remoteVideo;
        if (element.requestFullscreen) {
            element.requestFullscreen();
        } else if (element.msRequestFullscreen) {
            element.msRequestFullscreen();
        } else if (element.mozRequestFullScreen) {
            element.mozRequestFullScreen();
        } else if (element.webkitRequestFullscreen) {
            element.webkitRequestFullscreen();
        }
    };
    static createView = function (videoId) {
        var res = null;
        try{
            res = document.createElement('video');
            //res.style.width="100%";
            //res.style.height="100%";
            res.setAttribute('width','100%');
            res.setAttribute('height','100%');
            res.setAttribute('autoplay','true');
            res.id = ThhuKms.isNull(videoId)?ThhuChannel.newId('viewVideo_',''):videoId;
        }
        catch (e) {
            console.log(e)
        }
        return res;
    };
}
class ThhuChannel{
    constructor(channelId , channelInfo , channelPipeId){
        var me = this;
        try{
            me.channelId=channelId;
            me.pipeKmsId=channelPipeId;
            me.channelInfo=channelInfo;
        }
        catch (e) {
            console.log(e);
        }
    };
    config={
        kurentUrl: "wss://wss.hhdata.cn:8433/kurento"
    };
    objs={
        kmsClient : null,
        pipe: null
    };
    getKmsClient = function (callback) {
        var me = this;
        try{
            if( me.objs.kmsClient  && me.objs.kmsClient!=null){
                ThhuKms.cb(callback,me.objs.kmsClient);
            }
            else{
                kurentoClient(me.config.kurentUrl, function (error, client) {
                    if (client) {
                        client.getServerManager(function (erSvr , svr) {
                            client.serverManager = svr;
                            me.objs.kmsClient = client;
                            ThhuKms.cb(callback,client);
                        })
                    }
                });
            }
        }
        catch (e) {
            console.log(e);
        }
    };
    getChannelPipe = function (callback) {
        var me = this;
        try{
            if( ThhuKms.isNull(me.objs.pipe) ){
                me.getKmsClient(function (client) {
                    client.getMediaobjectById(me.pipeKmsId, function (erFind , pipe) {
                        if( pipe){
                            me.objs.pipe = pipe;
                            ThhuKms.cb(callback , pipe);
                        }
                        else {
                            client.create("MediaPipeline", function (erNewPipe , np) {
                                np.setName( me.channelId, function (erSetName) {
                                    np.addTag("chnnelInfo", JSON.stringify(me.channelInfo), function (erTag) {
                                        me.objs.pipe = np;
                                        me.pipeKmsId = np.id;
                                        ThhuKms.cb(callback , np);
                                    })
                                })
                            })
                        }
                    })
                })
            }
            else{
                ThhuKms.cb(callback , me.objs.pipe);
            }
        }
        catch (e) {
            console.log(e);
        }
    };
}
class ThhuClient{
    constructor(channelId , clientId , tag , onRemoteClientOnline,  onRemoteClientOffline, onMsg,   onConnect , onDisConnect ){
        var me = this;
        try{
            me.config.channelId = channelId;
            me.config.tag =  ThhuKms.isNull(tag)?{}:tag;
            me.config.clientId = ThhuKms.isNull(clientId)?ThhuKms.newId(clientId):clientId;
            me.config.topics.channelTopic = "hhu/channel/"+me.config.channelId;
            me.config.topics.clientTopic = "hhu/client/"+me.config.channelId+"/";
            me.config.topics.willMsgTopic = "hhu/will/"+me.config.channelId;
            if( onRemoteClientOnline && onRemoteClientOnline!=null && typeof onRemoteClientOnline === "function"){
                me.events.onRemoteClientOnline = onRemoteClientOnline;
            }
            if( onRemoteClientOffline && onRemoteClientOffline!=null && typeof onRemoteClientOffline === "function"){
                me.events.onRemoteClientOffline = onRemoteClientOffline;
            }
            if( onConnect && onConnect!=null && typeof onConnect === "function"){
                me.events.onConnect = onConnect;
            }
            if( onDisConnect && onDisConnect!=null && typeof onDisConnect === "function"){
                me.events.onDisConnect = onDisConnect;
            }
            if( onMsg && onMsg!=null && typeof onMsg === "function"){
                me.events.onMsg = onMsgonMsg;
            }
        }
        catch (e) {
            console.log(e);
        }
    }
    config= {
        clientId:"",
        channelId:"",
        tag:{},
        host:"gmggf8g.mqtt.iot.bj.baidubce.com",
        port:443,
        uid:"gmggf8g/peer",
        pwd:"a52bwKg22dCAuQzB",
        topics:{
            channelTopic : "",
            clientTopic :"",
            willMsgTopic :""
        }
    };
    objs={
        mqClient: null,
        remoteClients:{}
    };
    events = {
        onConnect: function () {},
        onDisConnect: function () {},
        onRecMsg: function(msg , topic) {} ,
        onRemoteClientOnline : function (clientInfo) {} ,
        onRemoteClientOffline : function (clientInfo) {}
    };
    getClient = function () {
        var me = this;
        try{
            if( ThhuKms.isNull(me.objs.mqClient)){
                var onConnect = function () {
                    var channelTopic = (me.config.topics.channelTopic+"/#").replace("//","/");
                    var clientTopic = (me.config.topics.clientTopic+"/"+me.config.clientId+"/#").replace("//","/");
                    var willTopic = (me.config.topics.willMsgTopic+"/#").replace("//","/");
                    client.subscribe(channelTopic);
                    client.subscribe(clientTopic);
                    client.subscribe(willTopic);
                    ThhuKms.cb(me.events.onConnect);

                    var handler = function () {
                        var msg = {
                            msgId:"online",
                            msgBody:{
                                clientId:me.config.clientId ,
                                tag: me.config.tag
                            }
                        };
                        var topic = me.config.topics.channelTopic;
                        client.publish(topic , JSON.stringify(msg) , 0 , false);
                    };
                    window.setTimeout(handler, 1500)
                };
                var onDisConnect = function () {
                    ThhuKms.cb(me.events.onDisConnect);
                };
                var onRecMsg = function (msgData) {
                    var msg = JSON.parse(msgData.MsgContent);
                    if( msg.msgId=="online"){
                        me.objs.remoteClients[msg.msgBody.clientId] = msg.msgBody;
                        ThhuKms.cb(me.events.onRemoteClientOnline, msg.msgBody);
                        if(msg.msgBody.clientId != me.config.clientId) {
                            var topic = (me.config.topics.clientTopic+"/"+msg.msgBody.clientId ).replace("//","/");;
                            var newMsg = {
                                msgId:"welcome",
                                msgBody:{
                                    clientId:me.config.clientId ,
                                    tag: me.config.tag
                                }
                            };
                            client.publish(topic, JSON.stringify(newMsg), 0 , false);
                        }
                    }
                    else if( msg.msgId=="welcome"){
                        me.objs.remoteClients[msg.msgBody.clientId] = msg.msgBody;
                        ThhuKms.cb(me.events.onRemoteClientOnline, msg.msgBody);
                    }
                    else if( msg.msgId=="offline"){
                        if (me.objs.remoteClients[msg.msgBody.clientId]) {
                            delete me.objs.remoteClients[msg.msgBody.clientId] ;
                            ThhuKms.cb(me.events.onRemoteClientOffline, msg.msgBody);
                        }
                    }
                    else {
                        ThhuKms.cb(me.events.onRecMsg, msg, msgData.topic );
                    }
                };
                var willTopic = me.config.topics.willMsgTopic;
                var willMsg = {
                    msgId:"offline" ,
                    msgBody:{
                        clientId: me.config.clientId ,
                        tag: me.config.tag
                    }
                }
                var client = createMqClient(
                    me.config.host,
                    me.config.port,
                    me.config.uid,
                    me.config.pwd,
                    me.config.clientId,
                    "",
                    1, willTopic, willMsg,
                    onConnect, onDisConnect, onRecMsg
                );
                me.objs.mqClient = client;
            }
        }
        catch (e) {
            console.log(e);
        }
        return me.objs.mqClient;
    };
    connect= function () {
        var me = this;
        try {
            var client = me.getClient();
            var opts = client.connectionOptions;
            client.connect(opts);
        }
        catch (e) {
            console.log(e)
        }
    };
}
class ThhuView{
    constructor(channel , viewId , viewType, localVideo , remoteVideo){
        var me = this;
        try{
            me.objs.channel = channel;
            me.viewId  = ThhuKms.isNull(viewId)?ThhuKms.newId('hhuView',''):viewId;
            me.viewType = viewType;
            if( ThhuKms.isNull(localVideo)){
                me.objs.localVideo = ThhuKms.createView('viewVideo_local_'+ me.viewId);
            }
            else{
                me.objs.localVideo = localVideo;
            }
            if( ThhuKms.isNull(remoteVideo)){
                me.objs.remoteVideo = ThhuKms.createView('viewVideo_remote_'+ me.viewId);
            }
            else{
                me.objs.remoteVideo = remoteVideo;
            }
        }
        catch (e) {
            console.log(e);
        }
    };
    objs = {
        channel: new ThhuChannel(),
        peer: null,
        end: null,
        localVideo: null,
        remoteVideo: null
    };
    initView = function( onInit  ){
        var me = this;
        try{
            var viewFactory = ThhuKms.kmsPeerTypeList[me.viewType];
            var opts = JSON.parse(JSON.stringify(ThhuKms.kmsPeerOptions));
            if( me.viewType==0 ){
                opts.localVideo = me.objs.localVideo;
            }
            else if( me.viewType==1 ){
                opts.remoteVideo = me.objs.remoteVideo;
            }
            else if( me.viewType==2 ){
                opts.localVideo = me.objs.localVideo;
                opts.localVideo = me.objs.remoteVideo;
            }
            var peer = viewFactory(opts, function () {
                me.objs.channel.getChannelPipe(function ( ) {
                    var pipe = me.objs.channel.objs.pipe;
                    pipe.create("WebRtcEndpoint", function (erEnd , end ) {
                        ThhuKms.kmsBindPeerEnd(peer , end , function () {
                            me.objs.peer = peer;
                            me.objs.end = end;
                            ThhuKms.cb( onInit );
                        })
                    })
                })
            })
        }
        catch (e) {
            console.log(e);
        }
    };
    close = function () {
        ;
    }
}
class ThhWxLoginData{
    wxAppId="heHaiXieTong";
    code="";
    state="";
    sysId="";
    action="";
    accessToken="";
    accessTokenTime=0;
    refreshToken="";
    refreshTokenTime=0;
    openId="";
    userInfo={};
};
class ThhWxLogin{
    config = {
        acs:{
            acNotifyhhRoomPc:{
                ac:'notify',
                topic:'wxLogin/notify/hhRoom'
            },
            acNotifyhhRoomMo:{
                ac:'redirect',
                url:'https://wss.hhdata.cn'
            }
        },
        redirectWxUrl :"https://open.weixin.qq.com/connect/oauth2/authorize?appid=[wxAppId]&redirect_uri=https%3A%2F%2Fwx.hhdata.cn%2Fapps%2Fwss%2FwxBridge.htm&response_type=code&scope=snsapi_userinfo&state=[state]#wechat_redirect"
    };
    data = new ThhWxLoginData();
    loadData = function () {
        var me = this;
        try{
            var aData = new ThhWxLoginData();
            me.data.state = hhls.getUrlParamByDefault('state',"");
            me.data.code = hhls.getUrlParamByDefault('code',"");
            var localKey = "ThhWxLogin.state."+ me.data.state;
            var info = hhls.loadLocalObj(localKey);
            if( !info || info==null){
                info = {};
            }

            var getValue = function (key  , defaultValue) {
                var res = defaultValue;
                var urlVal = hhls.getUrlParamByDefault(key, '');
                if( urlVal==""){
                    if( info[key] ){
                        res = info[key];
                    }
                }
                else{
                    res = urlVal;
                }
                return res;
            }

            var setValue = function (key, defaultValue) {
                var val = getValue(key,defaultValue);
                me.data[key]= val;
                //info[key] = val;
            }

            setValue("sysId",'');
            setValue("action",'');
            setValue("accessToken",'');
            setValue("accessTokenTime",0);
            setValue("refreshToken",'');
            setValue("refreshTokenTime",0);
            setValue("openId",'');

            me.data.callAction = me.config.acs[me.data.action];

            me.saveLocal();

        }
        catch (e) {
            console.log(e);
        }

    };
    getAccessTokenByCode = function (onGet) {
        var me = this;
        try{
            var ps = {
                wxAppId: me.data.wxAppId ,
                code : me.data.code
            };
            hhKmsClient.callApi("hhWxLoginGetAccessTokenByCode", ps, function (aRes) {
                var tokenInfo = aRes.data;
                if( tokenInfo&& tokenInfo!=null) {
                    var now = ( new Date()).getTime();
                    me.data.accessToken = tokenInfo.access_token;
                    me.data.refreshToken = tokenInfo.refresh_token;
                    me.data.openId = tokenInfo.openid;
                    me.data.accessTokenTime = now;
                    me.data.refreshTokenTime = now;
                    me.saveLocal();
                }
                onGet( );
            })
        }
        catch (e) {
            console.log(e);
        }
    };
    getAccessTokenByRefresh = function (onGet) {
        var me = this;
        try{
            var ps = {
                wxAppId: me.data.wxAppId ,
                refreshToken : me.data.refreshToken
            };
            hhKmsClient.callApi("hhWxLoginGetAccessTokenByRefresh", ps, function (aRes) {
                var tokenInfo = aRes.data;
                if( tokenInfo&& tokenInfo!=null) {
                    var now = ( new Date()).getTime();
                    me.data.accessToken = tokenInfo.access_token;
                    me.data.refreshToken = tokenInfo.refresh_token;
                    me.data.openId = tokenInfo.openid;
                    me.data.accessTokenTime = now;
                    me.saveLocal();
                }
                onGet( );
            })
        }
        catch (e) {
            console.log(e);
        }
    };
    getUserInfoByAccessToken = function (onGet) {
        var me = this;
        try{
            var ps = {
                wxAppId: me.data.wxAppId ,
                accessToken : me.data.accessToken ,
                openId : me.data.openId
            };
            hhKmsClient.callApi("hhWxLoginGetUserInfoByAccessToken", ps, function (aRes) {
                if( aRes.data) {
                    me.data.userInfo = aRes.data.userInfo;
                }
                else{
                    me.datas.userInfo={};
                }
                onGet();
            })
        }
        catch (e) {
            console.log(e);
        }
    };
    getRedirectUrl = function (onGet) {
        var me = this;
        try{
            var ps = {wxAppId: me.data.wxAppId , state : me.data.state};
            hhKmsClient.callApi("hhWxLoginGetRedirectUrl", ps, function (aRes) {
                onGet( aRes.data);
            });
        }
        catch (e) {
            console.log(e);
        }
    };
    redirect2WxUrl = function ( ) {
        var me = this;
        try{
            var state = me.data.state;
            //var url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx29435f02de2545d8&redirect_uri=https%3A%2F%2Fwx.hhdata.cn%2Fapps%2Fwss%2FwxBridge.htm&response_type=code&scope=snsapi_userinfo&state="+state+"#wechat_redirect";
            var url = me.config.redirectWxUrl.replace("[wxAppId]",me.data.wxAppId).replace("[state]",me.data.state);
            hhls.goUrl(url);
        }
        catch (e) {
            console.log(e);
        }
    };
    saveLocal = function ( ) {
        var me = this;
        try{
            var info = {
                sysId: me.data.sysId ,
                action: me.data.action ,
                accessToken: me.data.accessToken ,
                accessTokenTime: me.data.accessTokenTime ,
                refreshToken: me.data.refreshToken ,
                refreshTokenTime: me.data.refreshTokenTime ,
                openId: me.data.openId
            };
            var localKey = "ThhWxLogin.state."+ me.data.state;
            hhls.saveLocalObj(localKey, info);
        }
        catch (e) {
            console.log(e);
        }
    };
    apply = function (onApply) {
        var me = this;
        try{
            me.loadData();
            var now = ( new Date()).getTime();
            if( me.data.code ==""){
                var refreshTimeoutFlag = ( now - me.data.refreshTokenTime ) > 28 * 24 * 3600 * 1000;
                var accessTimeoutFlag = ( now - me.data.accessTokenTime ) > 6300 * 1000;
                if( refreshTimeoutFlag){
                    me.getRedirectUrl(function (url) { var res ={
                        status:-1,
                            url:url
                        }
                        onApply(res);
                    })
                }
                else if( accessTimeoutFlag){
                    me.getAccessTokenByRefresh(function () {
                        me.getUserInfoByAccessToken(function () {
                            var res ={
                                status:1,
                                userInfo:me.data.userInfo
                            }
                            onApply(res);
                        })
                    })
                }
                else{
                    me.getUserInfoByAccessToken(function () {
                            var res ={
                                status:1,
                                userInfo:me.data.userInfo
                            }
                            onApply(res);
                    })
                }
            }
            else{
                me.getAccessTokenByCode(function () {
                    me.getUserInfoByAccessToken(function () {
                            var res ={
                                status:1,
                                userInfo:me.data.userInfo
                            }
                            onApply(res);
                    })
                })
            }
        }
        catch (e) {
            console.log(e);
        }
    }
};



var hhKmsClient ={
    config:{
        appid:"hhroom",
        apiUrl:"https://wss.hhdata.cn:20024/hhapi",
        clientId:ThhuKms.newId('clientId')
    },
    callApi: function (ac , ps , callback) {
        var me = hhKmsClient;
        try{
            var aUrl = me.config.apiUrl;
            aUrl += "/"+ac;
            aUrl += aUrl.indexOf("?")>0?"&":"?";
            aUrl += "rt="+(new Date()).getTime().toString()+"."+Math.random().toString();
            $.ajax({
                url:aUrl ,
                data:JSON.stringify(ps) ,
                contentType: "application/json; charset=utf-8", //必须有
                dataType: "json", //表示返回值类型，不必须
                type:"post",
                success: function (res) {
                    console.log(res);
                    hhls.callBack(callback , res);
                },
                error: function (e0,e1) {
                    console.log(e0, e1);
                    hhls.callBack(callback , e0 , e1);
                }
            })
        }
        catch (e) {
            console.log(e);
        }
    },
    getSvrTime: function ( callback) {
        var me = hhKmsClient;
        try{
            me.callApi('getSvrTime', {}, function (res) {
                callback(res.data);
            })
        }
        catch (e) {
            console.log(e);
        }
    },
    wxCreateLoginQr: function(divId){
        var me = hhKmsClient;
        url = "https://wss.hhdata.cn:20024/apps/hhroom/wxlogin.html?sysId="+me.config.appid+"&clientId="+me.config.clientId;
        var qrcode = new QRCode(document.getElementById(divId), {
            text: url,
            width: 280,
            height: 280,
            colorDark : "#000000",
            colorLight : "#ffffff",
            correctLevel : QRCode.CorrectLevel.H
        });
    },
    wxGetAccessTokenUserInfo: function (ak ,callback) {
        var me = hhKmsClient;
        try{
            var localKey = "wxLogin."+ ak;
            var localInfo = hhls.loadLocalObj(localKey);
            localInfo = localInfo == null ? {} :  localInfo;
            var ps = {
                ak: ak,
                code:code ,
                tag : tag ,
                openId:localInfo['openId']?localInfo['openId']:"" ,
                accessToken :localInfo['accessToken']?localInfo['accessToken']:"",
                accessTime:localInfo['accessTime']?localInfo['accessTime']:0,
                refreshToken:localInfo['refreshToken']?localInfo['refreshToken']:"",
                refreshTime:localInfo['refreshTime']?localInfo['refreshTime']:0,
            };
            me.callApi("wxLogin" , ps , function (res) {
                if( res.data && res.data.status==1){
                    var info = res.data.data;
                    hhls.saveLocalObj(localKey , info);
                }
                hhls.callBack(callback , res);
            })
        }
        catch (e) {
            console.log(e);
        }
    },
    dbQuery: function (appId , key , queryPs , callback) {
        var me = hhKmsClient;
        try{
            var ps = {
                appId: appId ,
                key: key ,
                ps:JSON.stringify(queryPs)
            }
            me.callApi("dbQuery" , ps , function (res) {
                hhls.callBack(callback , res);
            })
        }
        catch (e) {
            console.log(e);
        }
    }
};